package cn.edu.xmist.springmvcconcurrentdemo.service.impl;

import cn.edu.xmist.springmvcconcurrentdemo.pojo.Request;
import cn.edu.xmist.springmvcconcurrentdemo.remote.service.RemoteOrderService;
import cn.edu.xmist.springmvcconcurrentdemo.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.*;

/**
 * @author zhongjinbin 2021/3/26
 * @since
 */
//标识这是一个服务
@Service
public class OrderServiceImpl implements OrderService {

    LinkedBlockingDeque<Request> car = new LinkedBlockingDeque<>();

    @Autowired
    // 远程订单服务(如第三方服务)
    RemoteOrderService remoteOrderService;

    @Override
    public Map<String, Object> queryOrderInfo(String orderCode) throws ExecutionException, InterruptedException {
        String serialNo = UUID.randomUUID().toString();
        CompletableFuture<Map<String, Object>> wife = new CompletableFuture<>();

        Request request = new Request();
        request.setOrderCode(orderCode);
        request.setSerialNo(serialNo);
        request.setWife(wife);

        // 加入到消息队列
        car.add(request);

        // get()为阻塞，通过complete()唤醒
        return wife.get();
    }

    // 类启动时执行
    @PostConstruct
    public void init() {
        /**
         * 定时循环查看消息队列有没有数据
         */
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                int size = car.size();
                if (size == 0) {
                    return;
                }

                /**
                 * 批量参数对象
                 */
                List<Request> requests = new ArrayList<>();
                List<Map<String, String>> params = new ArrayList<>();
                for (int i = 0; i < size; i++) {
                    Request request = car.poll();
                    Map<String, String> param = new HashMap<>();
                    param.put("orderCode", request.getOrderCode());
                    param.put("serialNo", request.getSerialNo());
                    params.add(param);

                    /**
                     * 方便下面批量获取返回结果
                     */
                    requests.add(request);
                }

                System.out.println("本次批量处理了数据量：" + size);

                List<Map<String, Object>> results = remoteOrderService.queryOrderInfoByBatchOrderCode(params);

                /**
                 * 批量分治合并请求获取批量结果
                 */
                if (results != null) {
                    for (Request request : requests) {
                        String serialNo = request.getSerialNo();
                        for (Map<String, Object> result : results) {
                            String resSerialNo = (String)result.get("serialNo");
                            if (serialNo.equals(resSerialNo)) {
                                /**
                                 * 这边会唤醒get()阻塞的线程获取结果
                                 */
                                request.getWife().complete(result);
                            }
                        }
                    }
                }

            }
        }, 0, 10, TimeUnit.MILLISECONDS);
    }
}
